package network;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Hashtable;
import java.io.InputStreamReader;

import org.json.JSONException;
import org.json.JSONObject;

import server.LocalGame;

import core.Card;
import core.Game;
import core.Player;
import core.ResourceType;
/**
 * The server-side proxy for a local player class, but treat it as any player. It will forward
 * messages which will be received and parsed by NetworkGame, which will call the appropriate
 * methods on the Player class.
 * @author CodyS
 *
 */
public class NetworkPlayer extends Player implements Messager {
	private Socket connect;
	private BufferedReader reader;
	private PrintWriter writer;
	private String name;
	private Hashtable<ResourceType,Integer> res;
	private ArrayList<Card> devcards;
	private int usedArmies = 0;
	private Color myCoolColour;
	public NetworkPlayer(Game g,Socket s) {
		super(g);
		connect = s;
		res = new Hashtable<ResourceType,Integer>();
		devcards = new ArrayList<Card>();
		for(ResourceType rt : ResourceType.values()) {
			res.put(rt,0);
		}
		try {
			reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
			writer = new PrintWriter(s.getOutputStream());
			Thread t = new Thread(new NetworkListener(this,reader));
			t.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public JSONObject makeMessage(String command) {
		JSONObject jo = new JSONObject();
		try {
			jo.put("command", command);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jo;
	}
	/**
	 * Receive a message and call the appropriate methods on the LocalGame class.
	 * @param message The message to send
	 */
	public void receive(JSONObject message) {
		String command = "";
		try {
			command = message.getString("command");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		///TODO: helladays
	}
	/**
	 * Send a message to the NetworkGame class to be parsed
	 * @param message The message to send.
	 */
	@Override
	public void send(JSONObject jo) {
		writer.println(jo.toString());
		writer.flush();
	}

	@Override
	public void leave() {
		getGame().removePlayer(this);
		try {
			reader.close();
			writer.close();
			connect.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	/**
	 * Tells the player that it is his turn and that he should add to the counter.
	 */
	public void doTurn() {
		send(makeMessage("turn"));
	}

	@Override
	/**
	 * Tells the player to decide if he is ready or not.
	 */
	public void ready() {
		send(makeMessage("ready"));
	}

	@Override
	/**
	 * Tell the player that the game has started.
	 */
	public void started() {
		send(makeMessage("start"));
	}
	@Override
	public void addCard(Card c) {
		devcards.add(c);
		JSONObject msg = makeMessage("got card");
		try {
			msg.put("card", c.toJSON());
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	@Override
	public void addResource(ResourceType rt, int number) {
		res.put(rt, res.get(rt)+number);
	}
	@Override
	public int amount(ResourceType rt) {
		return res.get(rt);
	}
	@Override
	public int getArmies() {
		return usedArmies;
	}
	@Override
	public Color getColor() {
		return myCoolColour;
	}
	@Override
	public String getName() {
		return name;
	}
	@Override
	public int getRoadLength() {
		// TODO magix
		return 0;
	}
	@Override
	public int getVictoryPoints() {
		// TODO stuff
		return 0;
	}
	@Override
	public void loseCards() {
		send(makeMessage("discard"));
	}
	@Override
	public void notifyRobber() {
		send(makeMessage("move robber"));
	}
	@Override
	public void notifySteal() {
		send(makeMessage("choose steal"));
	}
	@Override
	public void notifyTrade(Hashtable<ResourceType, Integer> offer,
			Hashtable<ResourceType, Integer> ret) {
		JSONObject data = makeMessage("trade offer");
		try {
			data.put("offer", offer);
			data.put("ret", ret);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		send(data);
		
	}
	@Override
	public void removeCard(Card c) {
		JSONObject message = makeMessage("lost card");
		try {
			message.put("card", c.toJSON());
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		send(message);
	}
	@Override
	public void removeResoruce(ResourceType rt, int number) {
		res.put(rt, res.get(rt)-number);
		JSONObject message = makeMessage("lost resource");
		try {
			message.put("type",rt.toString());
			message.put("number", number);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	@Override
	public int totalResources() {
		int sum = 0;
		for(ResourceType rt : ResourceType.values()) {
			sum += res.get(rt);
		}
		return sum;
	}
	@Override
	public void updateGameState() {
		JSONObject jo = makeMessage("update");
		try {
			jo.put("game",((LocalGame)getGame()).toJSON());
			jo.put("cards",devcards);
			jo.put("resources", res);
		} catch(Exception e) {
			e.printStackTrace();
		}
		send(jo);
	}
	@Override
	public int getCitiesLeft() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public int getHousesLeft() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public int getRoadsLeft() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public int getTotalCards() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public boolean hasLargestArmy() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public boolean hasLongestRoad() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public boolean isTurn() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public int getResources(ResourceType resource) {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void notifyDiscard(int discard) {
		// TODO Auto-generated method stub
		
	}
}
